package game.games.world;

import game.GameListener;
import game.GraphicUtil;
import game.Position;
import game.cellmap.AbstractCellMapGame;
import game.cellmap.CellMap;
import game.coord.MapGenerator;
import game.scrollable.INeverScrollable;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.List;

import javax.swing.SwingUtilities;

public class World extends AbstractCellMapGame<CellMap> implements INeverScrollable
{
    private static World instance;
    
    public synchronized static World getInstance()
    {
        if (instance == null)
        {
            synchronized (World.class)
            {
                instance = new World();
            }
        }
        return instance;
    }
    
    private List<Region> regions;
    private ZoneType     currentZoneType = ZoneType.ALL[0];
    private Region       mouseOverRegion = new Region();
    
    public World()
    {
        super(false, new CellMap(false, Region.getMapSize()));
        mouseOverRegion.overrideZoneTypes(currentZoneType);
        final GameListener gameListener = GameListener.getInstance();
        gameListener.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                if (isRunning())
                {
                    if (SwingUtilities.isRightMouseButton(e))
                    {
                        int index = currentZoneType.ordinal();
                        // next
                        index++;
                        if (index == ZoneType.ALL.length)
                        {
                            index = 0;
                        }
                        currentZoneType = ZoneType.ALL[index];
                        mouseOverRegion.overrideZoneTypes(currentZoneType);
                    }
                    else if (SwingUtilities.isLeftMouseButton(e))
                    {
                        if (getMouseOverIndex() >= 0)
                        {
                            if (getMouseOverIndex() >= 0)
                            {
                                regions.get(getMouseOverIndex()).overrideZoneTypes(currentZoneType);
                            }
                        }
                    }
                }
            }
        });
        gameListener.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e)
            {
                if (isRunning())
                {
                    if (SwingUtilities.isLeftMouseButton(e))
                    {
                        if (getMouseOverIndex() >= 0)
                        {
                            regions.get(getMouseOverIndex()).overrideZoneTypes(currentZoneType);
                        }
                    }
                }
            }
        });
    }
    
    @Override
    public void render(Graphics g)
    {
        GraphicUtil.clearScreen((Graphics2D) g, getFrameSize().width, getFrameSize().height);
        if (isRunning())
        {
            for (int index = 0; index < regions.size(); index++)
            {
                Region region = null;
                if (index == getMouseOverIndex())
                {
                    region = mouseOverRegion;
                }
                else
                {
                    region = regions.get(index);
                }
                Position position = getMap().calculatePosition(index);
                // image
                GraphicUtil.drawImage(g, position.getX(), position.getY(), region.getImage());
            }
        }
        else
        {
            GraphicUtil.renderCenterText(g, "Status: " + getStatus(), 30, new Position(getFrameSize()));
        }
        super.render(g);
    }
    
    @Override
    public void doNext()
    {
    }
    
    @Override
    public void recalcSize(Dimension windowSize)
    {
        Position maxSize = getMap().calcMaxSize(new Position(windowSize));
        getMap().setMapSize(maxSize);
        regions = MapGenerator.generateVonNeumannMap(getMap().calcMaxSize(new Position(getFrameSize())), Region.class);
    }
    
    @Override
    protected synchronized void reset()
    {
        recalcSize(getFrameSize());
        super.reset();
    }
    
    public static void main(String[] args)
    {
        Thread t = new Thread(World.getInstance(), "World");
        t.start();
    }
}
